﻿namespace FilteredPageReference
{
    using System;
    using System.Linq;
    using EPiServer.Core;
    using EPiServer.Core.PropertySettings;
    using EPiServer.Data.Dynamic;

    /// <summary>
    /// Property filtered page reference settings class
    /// </summary>
    [PropertySettingsUI(AdminControl = typeof(PropertyFilteredPageReferencePropertySettingsUI))]
    [EPiServerDataContract]
    [EPiServerDataStoreAttribute(AutomaticallyRemapStore = true)]
    [Serializable]
    public class PropertyFilteredPageReferenceSettings : PropertySettingsBase
    {

        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyFilteredPageReferenceSettings"/> class.
        /// </summary>
        public PropertyFilteredPageReferenceSettings()
        {
            PageTypeNames = string.Empty;
            StartFrom = PageReference.RootPage;
            StartFromCurrentPage = false;
            FullTypeNames = string.Empty;
            CurrentPageId = string.Empty;
            PopupHeight = 700;
            PopupWidth = 500;
        }

        /// <summary>
        /// Page picking start from delegate
        /// </summary>
        /// <param name="pagePickingStartPage">The <see cref="PagePickingStartPage"/> instance containing the event data.</param>
        public delegate void PagePickingStartPageDelegate(PagePickingStartPage pagePickingStartPage);

        /// <summary>
        /// Allowed page types delegate
        /// </summary>
        /// <param name="allowedPageTypes">The <see cref="AllowedPageTypes"/> instance containing the event data.</param>
        public delegate void AllowedPageTypesDelegate(AllowedPageTypes allowedPageTypes);

        /// <summary>
        /// Fires when start page is being retrieved
        /// </summary>
        public static PagePickingStartPageDelegate GetPagePickingStartPage { get; set; }

        /// <summary>
        /// Fires when allowed page types are being retrieved
        /// </summary>
        public static AllowedPageTypesDelegate GetAllowedPageTypes { get; set; }

        /// <summary>
        /// Gets or sets the page type names.
        /// </summary>
        /// <value>
        /// The page type names.
        /// </value>
        [EPiServerDataMember]
        public string PageTypeNames { get; set; }

        /// <summary>
        /// Gets or sets the tree start.
        /// </summary>
        /// <value>
        /// The tree start.
        /// </value>
        [EPiServerDataMember]
        public PageReference StartFrom { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [start from current page].
        /// </summary>
        /// <value>
        /// <c>true</c> if [start from current page]; otherwise, <c>false</c>.
        /// </value>
        [EPiServerDataMember]
        public bool StartFromCurrentPage { get; set; }

        /// <summary>
        /// Gets or sets the full name of the type.
        /// </summary>
        /// <value>
        /// The full name of the type.
        /// </value>
        [EPiServerDataMember]
        public string FullTypeNames { get; set; }

        /// <summary>
        /// Gets or sets the allowed page types and interfaces.
        /// </summary>
        /// <value>
        /// The allowed page types and interfaces.
        /// </value>
        public Type[] AllowedPageTypesAndInterfaces
        { 
            get
            {
                return FullTypeNames.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                    .Select(Type.GetType)
                    .Where(allowedType => allowedType != null).ToArray();
            }
            set
            {
                string typeNames = value.Aggregate(string.Empty, (current, allowedType) => current + string.Concat(allowedType.FullName, ","));
                FullTypeNames = typeNames.TrimEnd(',');
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether page selection should be restricted to EPiServer pages.
        /// </summary>
        /// <value>
        /// <c>true</c> if page selection should be restricted to EPiServer pages; otherwise, <c>false</c>.
        /// </value>
        [EPiServerDataMember]
        public bool RestrictToEPiServerPages { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether to start from the current sites start page.
        /// </summary>
        /// <value>
        /// <c>true</c> if picking should start from the current sites start page; otherwise, <c>false</c>.
        /// </value>
        [EPiServerDataMember]
        public bool StartFromCurrentSiteStartPage { get; set; }

        /// <summary>
        /// Gets or sets the validation error message.
        /// </summary>
        /// <value>
        /// The validation error message.
        /// </value>
        [EPiServerDataMember]
        public string ValidationErrorMessage { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [allow quick edit].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [allow quick edit]; otherwise, <c>false</c>.
        /// </value>
        [EPiServerDataMember]
        public bool AllowQuickEdit { get; set; }

        /// <summary>
        /// Gets or sets the current page id.
        /// </summary>
        /// <value>
        /// The current page id.
        /// </value>
        [EPiServerDataMember]
        public string CurrentPageId { get; set; }

        /// <summary>
        /// Gets or sets the height of the popup.
        /// </summary>
        /// <value>
        /// The height of the popup.
        /// </value>
        [EPiServerDataMember]
        public int PopupHeight { get; set; }

        /// <summary>
        /// Gets or sets the width of the popup.
        /// </summary>
        /// <value>
        /// The width of the popup.
        /// </value>
        [EPiServerDataMember]
        public int PopupWidth { get; set; }

        #region IPropertySettings Members

        /// <summary>
        /// Copies this instance.
        /// </summary>
        /// <returns>IPropertySettings instance</returns>
        public override IPropertySettings Copy()
        {
            PropertyFilteredPageReferenceSettings settings = new PropertyFilteredPageReferenceSettings();
            settings.Id = Guid.NewGuid();
            settings.PageTypeNames = PageTypeNames;
            settings.FullTypeNames = FullTypeNames;
            settings.StartFrom = StartFrom;
            settings.StartFromCurrentPage = StartFromCurrentPage;
            settings.RestrictToEPiServerPages = RestrictToEPiServerPages;
            settings.StartFromCurrentSiteStartPage = StartFromCurrentSiteStartPage;
            settings.ValidationErrorMessage = ValidationErrorMessage;
            settings.AllowQuickEdit = AllowQuickEdit;
            settings.CurrentPageId = string.Empty;
            settings.PopupHeight = PopupHeight;
            settings.PopupWidth = PopupWidth;
            return settings;
        }

        /// <summary>
        /// Gets the default values.
        /// </summary>
        /// <returns>IPropertySettings instance</returns>
        public override IPropertySettings GetDefaultValues()
        {
            return new PropertyFilteredPageReferenceSettings();
        }

        #endregion
    }

}